package org.springboot.jwt.controller;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springboot.jwt.service.IJwtService;
import org.springboot.jwt.util.JwtUtils;
import org.springboot.jwt.util.Result;
import org.springboot.mybatis.dao.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.auth0.jwt.interfaces.DecodedJWT;

@RestController
@RequestMapping("/jwt")
public class JwtController {

	/**
	 * JWT 的组成：
	 *  头部（Header）：头部通常由两部分组成，即令牌的类型（通常使用 “JWT”）和所使用的算法（如 HMAC SHA256 或 RSA）
	 *  载荷（Payload）：载荷包含有关声明或实体的声明。载荷可以包含例如用户名、用户ID、角色等相关信息。此外，JWT 还可以包含其他自定义的声明
	 *  签名（Signature）：签名部分用于验证令牌的真实性，并确保它未被篡改。签名是通过将头部、载荷和一个秘密密钥进行加密生成的
	 * 
	 * JWT 工作原理:
	 *  客户端通过身份验证成功后，服务器将生成一个 JWT。
	 *  服务器将 JWT 发送给客户端，并存储在客户端（通常是在 Cookie 或本地存储中）。
	 *  客户端在每次请求时将 JWT 添加到请求的头部或参数中。
	 *  服务器接收到请求后使用相同的密钥来验证 JWT 的真实性和完整性。
	 *  如果验证成功，服务器根据 JWT 中的声明完成对用户的身份验证和授权操作。
	 * 
	 * JWT 的应用场景: 用户认证、单点登录、API授权等。
	 */
	
	private static final Logger logger = LoggerFactory.getLogger(JwtController.class);
	
	@Autowired
	private IJwtService jwtService;
	
    @GetMapping("/login")
    public Result<Map<String, Object>> login(User user) {
        // 打印用户名和密码
    	logger.info("用户名: [{}]", user.getName());
    	logger.info("密码: [{}]", user.getPassword());
        // 创建结果对象
        Result<Map<String, Object>> result;
        try {
            // 调用userService的login方法进行用户认证
            User userDB = jwtService.login(user);
            // 生成JWT的令牌, 获取用户ID和用户名，并将其放入payload
            String token = JwtUtils.getToken(userDB.getId().toString());
            // 构造成功的结果对象
            result = new Result<>(200, "认证成功");
            result.setData(new HashMap<>());
            result.getData().put("token", token); // 响应token
        } catch (Exception e) {
            // 构造失败的结果对象
            result = Result.fail(500, e.getMessage());
        }
        return result;
    }
    
    @PostMapping("/test")
    public Result<Map<String, Object>> test(HttpServletRequest request) {
        // 创建结果对象
        Result<Map<String, Object>> result;
        try {
            Map<String, Object> map = new HashMap<>();
            // 处理自己的业务逻辑
            // 从请求头中获取token
            String token = request.getHeader("token");
            // 校验并解析token
            DecodedJWT verify = JwtUtils.verify(token);
            // 打印解析出的用户id和用户名
            logger.info("用户username: [{}]", verify.getClaim("username").asString());
            // 构造成功的结果对象
            result = new Result<>(200, "请求成功!");
            result.setData(map);
        } catch (Exception e) {
            // 构造失败的结果对象
            result = Result.fail(500, e.getMessage());
        }
        return result;
    }

}
